package com.myk.game.lib.base;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.viewbinding.ViewBinding;

import com.myk.game.lib.LoopTimer;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义基础页面
 */
public abstract class AbsBasePage<VB extends ViewBinding> extends ViewGroup {

    protected VB binding;
    public final Context context;
    private final List<LoopTimer> loopTimerList;
    public Runnable onBackPressedCallback;

    public AbsBasePage(@NonNull Context context) {
        super(context, null, 0);
        this.context = context;
        loopTimerList = new ArrayList<>();
        try {
            ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
            Class<VB> clazz = (Class<VB>) type.getActualTypeArguments()[0];
            Method inflate = clazz.getDeclaredMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
            binding = (VB) inflate.invoke(null, LayoutInflater.from(getContext()), this, true);
        }
        catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                child.layout(l, t, r, b);
            }
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        for (LoopTimer loopTimer : loopTimerList) {
            loopTimer.stop();
        }
        binding = null;
    }

    /**
     * 添加一个定时循环任务
     */
    public final LoopTimer addLoopRunnable(long intervalMillis, Runnable runnable) {
        LoopTimer loopTimer = new LoopTimer(runnable, intervalMillis);
        loopTimer.delayStart();
        loopTimerList.add(loopTimer);
        return loopTimer;
    }

    /**
     * 添加一个定时定次循环任务
     */
    public final LoopTimer addLoopRunnable(int loopTimes, long intervalMillis, Runnable runnable) {
        LoopTimer loopTimer = new LoopTimer(runnable, intervalMillis, loopTimes);
        loopTimer.delayStart();
        loopTimerList.add(loopTimer);
        return loopTimer;
    }

    /**
     * 添加一个延迟任务
     */
    public final LoopTimer addDelayRunnable(long delayTime, Runnable runnable) {
        LoopTimer loopTimer = new LoopTimer(runnable, delayTime, 1);
        loopTimer.delayStart();
        loopTimerList.add(loopTimer);
        return loopTimer;
    }

    /**
     * 跳转到其它页面
     */
    protected void jumpPageTo(Class<? extends AbsBasePage<?>> clazz) {
        try {
            PageContainer parent = (PageContainer) getParent();
            Constructor<? extends AbsBasePage<?>> ctor = clazz.getConstructor(Context.class);
            AbsBasePage<?> page = ctor.newInstance(parent.getContext());
            parent.setPage(page);
        }
        catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }

    /**
     * 跳转到其它页面
     */
    protected void jumpPageTo(AbsBasePage<? extends ViewBinding> page){
        PageContainer parent = (PageContainer) getParent();
        parent.setPage(page);
    }

    public void setOnBackPressed(Runnable callback){
        onBackPressedCallback = callback;
    }

}
